home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus 2004 #9
/
Amiga Plus CD - 2004 - No. 09.iso
/
amigaplus
/
tools
/
amigaos4_only
/
fracblank
/
source
/
fraccommodity.c
< prev
next >
Wrap
C/C++ Source or Header
|
2004-08-03
|
10KB
|
369 lines
/*
** FracBlank - AmigaDOS 2.04 commodities utility screenblanker
**
** Copyright © 1991-1995 by Olaf `Olsen' Barthel
** All Rights Reserved
**
** Cosmic flame fractal code derived from xlock source code
**
** Copyright © 1988-1991 by Patrick J. Naughton.
*/
#include <dos/dos.h>
#include <libraries/commodities.h>
#include <proto/commodities.h>
#include <proto/datatypes.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include "Frac.h"
#include "FracCommodity.h"
// Commodities interface data
struct MsgPort *CxPort;
CxObj *Broker;
ULONG SpecialQualifier;
// A new broker definition, Commodities needs this
struct NewBroker NewBroker = {
NB_VERSION,
"FracBlank",
"Fractal screen blanker v2.3",
"Screen blanker",
NBU_NOTIFY | NBU_UNIQUE,
COF_SHOW_HIDE,
0,
NULL,
0
};
// Key sequence buffers
UBYTE HotkeyBuffer[256],
BlankScreenBuffer[256],
SaveScreenBuffer[256];
/* CustomHotKey(STRPTR Code,struct MsgPort *Port,LONG ID):
*
* A replacement for the HotKey() routine found in
* amiga.lib.
*/
CxObj *CustomHotKey(STRPTR Code, struct MsgPort *Port, LONG ID) {
CxObj *Filter;
if (Filter = ICommodities->CxFilter(Code)) {
CxObj *Sender;
if (Sender = ICommodities->CxSender(Port,ID)) {
CxObj *Translator;
ICommodities->AttachCxObj(Filter,Sender);
if (Translator = ICommodities->CxTranslate(NULL)) {
ICommodities->AttachCxObj(Filter,Translator);
if (!ICommodities->CxObjError(Filter)) return(Filter);
}
}
ICommodities->DeleteCxObjAll(Filter);
}
return(NULL);
}
/* BlankerAction(CxMsg *CxMessage,CxObj *CxObject):
*
* Commodities support routine, handles the Commodities
* custom actions (in this case: filter the InputEvents
* coming in and enable/disable the screen blanker).
*/
VOID BlankerAction(CxMsg *CxMessage, CxObj *CxObject) {
static BYTE Count = 0;
struct InputEvent *Event = (struct InputEvent *)ICommodities->CxMsgData(CxMessage);
// Push the blanker screen to the front if necessary
IExec->ObtainSemaphoreShared(&BlankSemaphore);
if (BlankScreen) IExec->Signal((struct Task *)BlankerControlProcess,SIG_REFRESH);
IExec->ReleaseSemaphore(&BlankSemaphore);
// This looks like a timer event
if (Event->ie_Class == IECLASS_TIMER) {
// if (!Window) {
if (TRUE) {
// Screen blanker still inactive?
IExec->ObtainSemaphoreShared(&BlankSemaphore);
if (!BlankTask) {
// Is there a timeout to take care of?
// if (ScreenTimeout && !Window) {
if (ScreenTimeout && TRUE) {
// Are we ready to create the
// screenblanker?
if (ScreenCount++ >= ScreenTimeout * 10) IExec->Signal((struct Task *)BlankerControlProcess,SIG_START);
}
}
else {
// Every 5/10 second we signal the blanker
// task to rotate the palette.
if (ColourMode == COLOUR_CYCLE) {
if (Count++ >= 2) {
IExec->Signal(BlankTask,CycleMask);
Count = 0;
}
}
// Is it time to change the pattern?
if (PatternTimeout) {
if (PatternCount++ >= PatternTimeout * 10) {
IExec->Signal((struct Task *)BlankerControlProcess,SIG_CHANGE);
PatternCount = 0;
}
}
}
IExec->ReleaseSemaphore(&BlankSemaphore);
}
}
else {
// The following lines determine whether
// the blanker is to be removed or to
// be left running.
switch(Event->ie_Class) {
case IECLASS_RAWKEY:
if (!(Event->ie_Code & IECODE_UP_PREFIX) && !(Event->ie_Qualifier & SpecialQualifier)) IExec->Signal((struct Task *)BlankerControlProcess,SIG_BREAK);
break;
case IECLASS_NEWPOINTERPOS:
case IECLASS_POINTERPOS:
case IECLASS_RAWMOUSE:
IExec->Signal((struct Task *)BlankerControlProcess,SIG_BREAK);
break;
}
ScreenCount = 0;
}
}
/* ShutdownCx():
*
* Close the Commodities interface.
*/
VOID ShutdownCx() {
if (CxPort) {
struct Message *Message;
// Remove the broker
if (Broker) ICommodities->DeleteCxObjAll(Broker);
// Remove the MsgPort from the public list
IExec->RemPort(CxPort);
// Remove all pending messages
while(Message = IExec->GetMsg(CxPort)) IExec->ReplyMsg(Message);
// Delete the MsgPort
IExec->DeleteMsgPort(CxPort);
CxPort = NULL;
Broker = NULL;
}
}
/* SetupCx():
*
* Set up the Commodities interface.
*/
LONG SetupCx() {
LONG Error;
// Cancel any previously made assignments
ShutdownCx();
// Create a reply port
if (CxPort = IExec->CreateMsgPort()) {
// Fill in a unique name
CxPort->mp_Node.ln_Name = NewBroker.nb_Name;
// Add the reply port to the public list
IExec->AddPort(CxPort);
// Install the replyport
NewBroker.nb_Port = CxPort;
// Create the broker
if (Broker = ICommodities->CxBroker(&NewBroker,&Error)) {
CxObj *ObjectList;
// Link the hotkeys
ICommodities->AttachCxObj(Broker,CustomHotKey(HotkeyBuffer, CxPort,POP_WINDOW));
ICommodities->AttachCxObj(Broker,CustomHotKey(BlankScreenBuffer, CxPort,BLANK_SCREEN));
ICommodities->AttachCxObj(Broker,CustomHotKey(SaveScreenBuffer, CxPort,SAVE_SCREEN));
// Install the plain InputEvent handler
ObjectList = ICommodities->CxCustom(BlankerAction,NULL);
// Any accumulated errors?
if (!(Error = ICommodities->CxObjError(ObjectList))) {
// Add the custom object
ICommodities->AttachCxObj(Broker,ObjectList);
// Any errors?
if (!(Error = ICommodities->CxObjError(Broker))) {
// Activate the broker
ICommodities->ActivateCxObj(Broker,TRUE);
return(0);
}
}
if (Error & COERR_BADFILTER) Error = ERR_BadFilter;
else {
if (Error & COERR_BADTYPE) Error = ERR_BadType;
else Error = ERROR_NO_FREE_STORE;
}
}
else Error = Error - CBERR_SYSERR + ERR_SystemError;
}
else Error = ERR_NoMsgPort;
ShutdownCx();
return(Error);
}
/* HandleCxMsg(CxMsg *Message):
*
* Handle incoming Commodities messages.
*/
VOID HandleCxMsg(CxMsg *Message) {
ULONG MessageID = ICommodities->CxMsgID(Message),
MessageType = ICommodities->CxMsgType(Message);
IExec->ReplyMsg((struct Message *)Message);
// Take a look at the message type
switch(MessageType) {
// It's a hotkey
case CXM_IEVENT:
switch(MessageID) {
// Create the control panel
case POP_WINDOW:
// Make sure the blanker has terminated
IExec->Signal((struct Task *)BlankerControlProcess,SIG_BREAK);
// SetupWindow();
break;
// Blank the screen
case BLANK_SCREEN:
// if (!Window) {
if (TRUE) {
IExec->ObtainSemaphoreShared(&BlankSemaphore);
if (!BlankTask) IExec->Signal((struct Task *)BlankerControlProcess,SIG_START);
else {
IExec->Signal((struct Task *)BlankerControlProcess,SIG_CHANGE);
PatternCount = 0;
}
IExec->ReleaseSemaphore(&BlankSemaphore);
}
break;
// Save the screen in the clipboard
case SAVE_SCREEN:
if (DataTypesBase) {
IExec->ObtainSemaphoreShared(&BlankSemaphore);
// Let the background process handle the job
if (BlankScreen && !Saver) {
IDOS->CreateNewProcTags(NP_Name, "« FracBlank Screen Saver »",
NP_Entry, SaverEntry,
NP_StackSize, 4096,
NP_WindowPtr, -1,
TAG_DONE);
}
IExec->ReleaseSemaphore(&BlankSemaphore);
}
break;
}
break;
// It's an internal Commodities command
case CXM_COMMAND:
switch(MessageID) {
// Disable the Commodity
case CXCMD_DISABLE:
ICommodities->ActivateCxObj(Broker,FALSE);
break;
// Enable the Commodity
case CXCMD_ENABLE:
ICommodities->ActivateCxObj(Broker,TRUE);
break;
// Create the control panel
case CXCMD_APPEAR:
case CXCMD_UNIQUE:
// SetupWindow();
break;
// Close the control panel
case CXCMD_DISAPPEAR:
// ShutdownWindow();
break;
// Remove this Commodity
case CXCMD_KILL:
CloseAll(RETURN_OK);
break;
}
break;
}
}
/* BuildMask(STRPTR Code):
*
* Build a mask of qualifiers covered by the given
* code.
*/
ULONG BuildMask(STRPTR Code) {
IX Expression;
if (!ICommodities->ParseIX(Code,&Expression)) {
ULONG Mask = 0,
Bits = Expression.ix_Qualifier & Expression.ix_QualMask;
// Are shift/caps lock keys involved?
if (Bits & IXSYM_CAPSMASK) {
// Are both shift keys equivalent?
if (Expression.ix_QualSame & IXSYM_SHIFT) Mask |= IXSYM_SHIFTMASK | (Bits & IEQUALIFIER_CAPSLOCK);
else {
// Are all shift/caps lock keys equivalent?
if (Expression.ix_QualSame & IXSYM_CAPS) Mask |= IXSYM_CAPSMASK;
else Mask |= Bits & IXSYM_CAPSMASK;
}
}
// Are alt keys involved?
if (Bits & IXSYM_ALTMASK) {
// Are both alt keys equivalent?
if (Expression.ix_QualSame & IXSYM_ALT) Mask |= IXSYM_ALTMASK;
else Mask |= Bits & IXSYM_ALTMASK;
}
// Take care of the remaining qualifiers
Mask |= Bits & ~(IXSYM_ALTMASK | IXSYM_CAPSMASK);
return(Mask);
}
else return(0);
}
/* AddQualifier(STRPTR Code,ULONG Qualifier):
*
* Add to the qualifier mask.
*/
ULONG AddQualifier(STRPTR Code,ULONG Qualifier) { return(Qualifier | BuildMask(Code)); }
/* SubQualifier(STRPTR Code,ULONG Qualifier):
*
* Remove keys from the qualifier mask.
*/
ULONG SubQualifier(STRPTR Code,ULONG Qualifier) { return(Qualifier & ~BuildMask(Code)); }